package com.ashlikun.wheelview_rv

import android.util.Log
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.ashlikun.wheelview_rv.WheelUtils.createLayoutParams

/**
 * @author　　: 李坤
 * 创建时间: 2024/7/23 13:45
 * 邮箱　　：496546144@qq.com
 *
 *
 * 功能介绍：处理留白的内部适配器
 */
internal class WheelWrapAdapter(
    var recyclerView: WheelRecyclerView,
    //外部适配器
    adapter: RecyclerView.Adapter<out ViewHolder>,
) : RecyclerView.Adapter<ViewHolder>() {
    val mAdapter: RecyclerView.Adapter<ViewHolder>
    val loopCount = Int.MAX_VALUE / 2

    //wheelview 滑动时上或下空白总数量 或者是循环时候的
    private val totalOffsetCount
        get() = recyclerView.offsetCount * 2
    private val mDataObserver: RecyclerView.AdapterDataObserver = object : RecyclerView.AdapterDataObserver() {
        override fun onChanged() {
            notifyDataSetChanged()
        }

        override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
            notifyItemRangeInserted(getFanActualPosition(positionStart) + positionStart, itemCount)
        }

        override fun onItemRangeChanged(positionStart: Int, itemCount: Int) {
            notifyItemRangeChanged(getFanActualPosition(positionStart) + positionStart, itemCount)
        }

        override fun onItemRangeChanged(positionStart: Int, itemCount: Int, payload: Any?) {
            Log.e("onItemRangeChanged", "onItemRangeChanged positionStart = $positionStart itemCount = $itemCount    ddddd ${getFanActualPosition(positionStart)}")
            notifyItemRangeChanged(getFanActualPosition(positionStart), itemCount, payload)
        }

        override fun onItemRangeRemoved(positionStart: Int, itemCount: Int) {
            notifyItemRangeRemoved(getFanActualPosition(positionStart) + positionStart, itemCount)
        }

        override fun onItemRangeMoved(fromPosition: Int, toPosition: Int, itemCount: Int) {
            notifyItemMoved(getFanActualPosition(fromPosition) + fromPosition, getFanActualPosition(toPosition) + toPosition)
        }
    }

    init {
        runCatching { adapter.unregisterAdapterDataObserver(mDataObserver) }
        adapter.registerAdapterDataObserver(mDataObserver)
        mAdapter = adapter as RecyclerView.Adapter<ViewHolder>
    }


    override fun getItemCount(): Int {
        if (mAdapter.itemCount == 0) return 0
        return if (recyclerView.isLoop) loopCount else totalOffsetCount + mAdapter.itemCount
    }

    override fun getItemViewType(position: Int): Int {
        if (recyclerView.isLoop) return mAdapter.getItemViewType(getActualPosition(position))
        return if (position < recyclerView.offsetCount || position >= mAdapter.itemCount + recyclerView.offsetCount) {
            EMPTY_TYPE
        } else mAdapter.getItemViewType(getActualPosition(position))
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val params = createLayoutParams(recyclerView.orientation, recyclerView.itemSize)
        if (viewType == EMPTY_TYPE) {
            val view = View(parent.context)
            view.layoutParams = params
            return EmptyViewHolder(view)
        }
        val vh = mAdapter.onCreateViewHolder(parent, viewType)
        if (vh.itemView.layoutParams == null) {
            vh.itemView.layoutParams = params
        } else {
            vh.itemView.layoutParams.width = params.width
            vh.itemView.layoutParams.height = params.height
        }
        return vh
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        if (holder.itemViewType == EMPTY_TYPE) return
//        holder.itemView.setOnClickListener {
//            Log.e("wwww", "wWrap onBindViewHolder $position,,,${getActualPosition(position)}")
//        }
//        Log.e("wwww", "Wrap onBindViewHolder $position,,,${getActualPosition(position)}")
        mAdapter.onBindViewHolder(holder, getActualPosition(position))
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int, payloads: MutableList<Any>) {
        if (holder.itemViewType == EMPTY_TYPE) return
//        Log.e("wwww", "Wrap2 onBindViewHolder $position,,,${getActualPosition(position)}")
//        holder.itemView.setOnClickListener {
//            Log.e("wwww", "wWrap onBindViewHolder $position,,,${getActualPosition(position)}")
//        }
        mAdapter.onBindViewHolder(holder, getActualPosition(position), payloads)
    }

    override fun onViewRecycled(holder: ViewHolder) {
        if (holder.itemViewType == EMPTY_TYPE) return
        mAdapter.onViewRecycled(holder)
    }

    override fun onViewAttachedToWindow(holder: ViewHolder) {
        if (holder.itemViewType == EMPTY_TYPE) return
        mAdapter.onViewAttachedToWindow(holder)
    }

    override fun onViewDetachedFromWindow(holder: ViewHolder) {
        if (holder.itemViewType == EMPTY_TYPE) return
        mAdapter.onViewDetachedFromWindow(holder)
    }

    override fun getItemId(position: Int): Long {
        val position = getActualPosition(position)
        if (position < 0) return super.getItemId(position)
        return mAdapter.getItemId(position)
    }

    override fun onAttachedToRecyclerView(rv: RecyclerView) {
        super.onAttachedToRecyclerView(rv)

        mAdapter.onAttachedToRecyclerView(rv)
    }

    override fun onDetachedFromRecyclerView(recyclerView: RecyclerView) {
        super.onDetachedFromRecyclerView(recyclerView)
        mAdapter.onDetachedFromRecyclerView(recyclerView)
    }

    /**
     * 空白ViewHolder
     */
    internal inner class EmptyViewHolder(itemView: View?) : ViewHolder(itemView!!)

    /**
     * 实际位置
     * @param position 内部位置
     * @return 外部位置
     */
    fun getActualPosition(position: Int) = if (recyclerView.isLoop) position % mAdapter.itemCount else position - recyclerView.offsetCount

    /**
     * 拿真实位置，转换成内部位置
     * @param position 真实位置
     */
    fun getFanActualPosition(position: Int): Int {
        if (recyclerView.isLoop) {
            //取当前中间位置,内部位置
            val first = WheelUtils.findFirstVisibleItemPosition(recyclerView!!.layoutManager!!)
            val firstStart = first / mAdapter.itemCount * mAdapter.itemCount
            val firstPage = firstStart / mAdapter.itemCount
            val firstReal = first - firstStart
            val last = WheelUtils.findLastVisiblePosition(recyclerView!!.layoutManager!!)
            val lastStart = last / mAdapter.itemCount * mAdapter.itemCount
            val lastReal = last - lastStart
            val lastPage = lastStart / mAdapter.itemCount
            val center = (first + last) / 2
            val centerStart = center / mAdapter.itemCount * mAdapter.itemCount
            if (lastPage != firstPage) {
                //不在同一页，判断更靠近哪个区间
                if (position in firstReal until mAdapter.itemCount) {
                    return firstStart + position
                } else if (position in 0..lastReal) {
                    return lastStart + position
                }
            }
//            if (firstStart + position >= mAdapter.itemCount) {
//                //越界，直接下一页
//                val diff = firstStart + position - mAdapter.itemCount
//            }

            return centerStart + position
        } else {
            return position + recyclerView.offsetCount
        }
    }

    fun getFirstPosition() = if (recyclerView.isLoop) loopCount / 2 - getActualPosition(loopCount / 2) - recyclerView.offsetCount
    else 0

    fun getCenterPosition() = if (recyclerView.isLoop) loopCount / 2 - getActualPosition(loopCount / 2) + mAdapter.itemCount / 2 - recyclerView.offsetCount
    else mAdapter.itemCount / 2 - recyclerView.offsetCount

    /**
     * 获取当前指定的position循环的第一个位置
     * @param position 内部位置
     */
    fun getPositionLoopFirstPosition(position: Int): Int {
        if (recyclerView.isLoop) {
            val page = position / mAdapter.itemCount
            return page * mAdapter.itemCount
        }
        return recyclerView.offsetCount
    }

    /**
     * 获取当前循环的第一个位置
     */
    fun getCurrentLoopFirstStartPosition(): Int {
        if (recyclerView.isLoop) {
            if (recyclerView?.layoutManager != null) {
                val first = WheelUtils.findFirstVisibleItemPosition(recyclerView!!.layoutManager!!)
                return first / mAdapter.itemCount * mAdapter.itemCount
            } else {
                return 0
            }
        }
        return recyclerView.offsetCount
    }


    companion object {
        /**
         * 空白状态
         */
        const val EMPTY_TYPE = 0x00000222
    }
}
